package com.ds.lens.data.service;

import com.ds.lens.data.service.dao.LensMonitorMuteInfoDao;
import com.ds.lens.data.service.dao.entity.LensMonitor;
import com.ds.lens.data.service.dao.entity.LensMonitorMuteInfo;
import com.ds.lens.data.util.DateTimeUtil;
import com.ds.lens.data.vo.in.User;
import com.ds.lens.data.vo.in.v2.downtime.LensScheduleDowntimeInVO;
import com.ds.lens.data.vo.in.v2.monitor.LensMonitorMuteInVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author WeiShaoying
 * @date 2019/11/20 下午5:42
 */
@Service
public class LensMonitorMuteService extends BaseService {

    @Autowired
    LensScheduleDowntimeService lensScheduleDowntimeService;

    @Autowired
    LensMonitorMuteInfoDao lensMonitorMuteInfoDao;

    @Transactional
    public Boolean muteMonitor(LensMonitorMuteInVO lensMonitorMuteInVO, User user) {
        List<LensMonitor> monitors = checkUserMonitorId(lensMonitorMuteInVO.getIds(), user);
        Date startTime = null;
        Date endTime = null;
        if (lensMonitorMuteInVO.getMute()) {
            startTime = new Date();
            int muteRange = lensMonitorMuteInVO.getMuteRange().getValue();
            if (muteRange > 0) {
                endTime = DateTimeUtil.dateAdd(4, startTime, muteRange);
            }
        }
        Date modifiedTime = new Date();
        lensMonitorDao.updateMuteByPrimaryKeys(lensMonitorMuteInVO.getIds(), lensMonitorMuteInVO.getMute(), startTime, endTime, modifiedTime);
        String content = getMuteEventContent(user.getUsername(), lensMonitorMuteInVO.getMute());
        Date muteStartTime = startTime;
        Date muteEndTime = endTime;
        monitors.forEach(lensMonitor -> {
            if (lensMonitorMuteInVO.getMute()) {
                lensScheduleDowntimeService.saveDowntime(getLensScheduleDowntimeInVO(lensMonitor, muteStartTime, muteEndTime), user);
            }
            processMonitorMuteState(lensMonitor, lensMonitorMuteInVO.getMute(), user.getUsername(), content);
        });
        return true;
    }

    @Transactional
    public void scheduleMuteMonitor(LensMonitor lensMonitor, String userName, Boolean mute, Date startTime, Date endTime, Boolean artificial) {
        Date modifiedTime = new Date();
        if (!mute) {
            startTime = null;
            endTime = null;
        } else if (!artificial && lensMonitor.getMute() && lensMonitor.getMuteEndTime() == null && endTime != null) {
            return;
        } else if (!artificial && lensMonitor.getMute() && lensMonitor.getMuteEndTime() != null && endTime != null
                && lensMonitor.getMuteEndTime().getTime() > endTime.getTime()) {
            return;
        }
        lensMonitorDao.updateMuteByPrimaryKeys(Collections.singletonList(lensMonitor.getId()), mute, startTime, endTime, modifiedTime);
        processMonitorMuteState(lensMonitor, mute, userName, getMuteEventContent(userName, mute));
    }

    public LensMonitor getMonitorById(Long id) {
        return lensMonitorDao.selectByPrimaryKey(id);
    }

    public List<LensMonitor> getMonitorByTags(Long applicationId, List<String> tags) {
        return lensMonitorDao.listByTagsAppId(applicationId, tags);
    }

    private LensScheduleDowntimeInVO getLensScheduleDowntimeInVO(LensMonitor lensMonitor, Date startTime, Date endTime) {
        LensScheduleDowntimeInVO lensScheduleDowntimeInVO = new LensScheduleDowntimeInVO();
        lensScheduleDowntimeInVO.setApplicationId(lensMonitor.getApplicationId());
        lensScheduleDowntimeInVO.setMonitorId(lensMonitor.getId());
        lensScheduleDowntimeInVO.setMonitorName(lensMonitor.getName());
        lensScheduleDowntimeInVO.setState(2);
        lensScheduleDowntimeInVO.setScheduleType(1);
        lensScheduleDowntimeInVO.setStartTime(startTime);
        lensScheduleDowntimeInVO.setEndTime(endTime);
        return lensScheduleDowntimeInVO;
    }

    private void processMonitorMuteState(LensMonitor lensMonitor, Boolean mute, String userName, String content) {
        LensMonitorMuteInfo lensMonitorMuteInfo = new LensMonitorMuteInfo();
        lensMonitorMuteInfo.setMonitorId(lensMonitor.getId());
        lensMonitorMuteInfo.setVersion(lensMonitor.getVersion());
        lensMonitorMuteInfo.setMute(mute);
        lensMonitorMuteInfo.setCreatedTime(new Date());
        lensMonitorMuteInfoDao.insert(lensMonitorMuteInfo);
        if (!mute) {
            lensScheduleDowntimeService.deleteDowntimeByMonitorId(lensMonitor.getId(), userName);
        }
        sendEvent(lensMonitor, content);
    }

    private String getMuteEventContent(String userName, Boolean mute) {
        StringBuilder str = new StringBuilder();
        str.append("告警被").append("用户[").append(userName).append("]")
                .append(mute ? "开启" : "取消").append("静默");
        return str.toString();
    }

}
